module get_ex_coord #(
    parameter 
        FRAME_LINE = 16'd640,
        FRAME_ROW  = 16'd480
)(
    input               clk         ,
    input               rst_n       ,
    input               diff_vsync  ,
    input               diff_href   ,
    input       [15:0]  diff_data   ,  // ffff or 0000(valid data)
    output              coord_vsync ,
    output              coord_href  ,
    output      [15:0]  coord_data  ,
    output reg  [15:0]  coord_x1    , // 0~1279
    output reg  [15:0]  coord_x2    ,
    output reg  [15:0]  coord_y1    , // 0~479
    output reg  [15:0]  coord_y2     
);
// reg
reg [15:0] row_cnt;
reg [15:0] line_cnt;
reg [15:0] valid_x;
reg [15:0] valid_y;
reg [15:0] coord_x1_r;
reg [15:0] coord_x2_r;
reg [15:0] coord_y1_r;
reg [15:0] coord_y2_r;
reg        diff_vsync_d1;

// wire
wire pos_diff_vsync;
wire neg_diff_vsync;
// main code----------------------------------------------------------------------
// coord_data
assign coord_data = diff_data;

// pos_diff_vsync
assign pos_diff_vsync = (~diff_vsync_d1) && diff_vsync;
assign neg_diff_vsync = diff_vsync_d1 && (~diff_vsync);

// diff_vsync_d1
always @(posedge clk or negedge rst_n) begin
    if(~rst_n)
        diff_vsync_d1 <= 1'd0;
    else
        diff_vsync_d1 <= diff_vsync;
end

// row_cnt
always @(posedge clk or negedge rst_n) begin
    if(~rst_n)
        row_cnt <= 16'd0;
    else if((line_cnt == (FRAME_LINE << 1) - 16'd1) && (row_cnt == FRAME_ROW - 16'd1))
        row_cnt <= 16'd0;
    else if(line_cnt == (FRAME_LINE << 1) - 16'd1)
        row_cnt <= row_cnt + 16'd1;
    else
        row_cnt <= row_cnt;
end

// line_cnt
always @(posedge clk or negedge rst_n) begin
    if(~rst_n)
        line_cnt <= 16'd0;
    else if(line_cnt == (FRAME_LINE << 1) - 16'd1)
        line_cnt <= 16'd0;
    else if(diff_href)
        line_cnt <= line_cnt + 16'd1;
    else
        line_cnt <= line_cnt;
end

// valid_x & valid_y
always @(posedge clk or negedge rst_n) begin
    if(~rst_n)begin
        valid_x <= 16'd0;
        valid_y <= 16'd0;
    end
    else if(diff_data == 16'hffff)begin
        valid_x <= line_cnt;
        valid_y <= row_cnt;
    end
    else begin
        valid_x <= valid_x;
        valid_y <= valid_y;
    end
end

// coord_x1_r
always @(posedge clk or negedge rst_n) begin
    if(~rst_n)
        coord_x1_r <= (FRAME_LINE << 1);
    else if(neg_diff_vsync)
        coord_x1_r <= (FRAME_LINE << 1);
    else if(valid_x < coord_x1_r)
        coord_x1_r <= valid_x;
    else
        coord_x1_r <= coord_x1_r;
end

// coord_x2_r
always @(posedge clk or negedge rst_n) begin
    if(~rst_n)
        coord_x2_r <= 16'd0;
    else if(neg_diff_vsync)
        coord_x2_r <= 16'd0;
    else if(valid_x > coord_x2_r)
        coord_x2_r <= valid_x;
    else
        coord_x2_r <= coord_x2_r;
end

// coord_y1_r
always @(posedge clk or negedge rst_n) begin
    if(~rst_n)
        coord_y1_r <= FRAME_ROW;
    else if(neg_diff_vsync)
        coord_y1_r <= FRAME_ROW;
    else if(valid_y < coord_y1_r)
        coord_y1_r <= valid_y;
    else
        coord_y1_r <= coord_y1_r;
end

// coord_y2_r
always @(posedge clk or negedge rst_n) begin
    if(~rst_n)
        coord_y2_r <= 16'd0;
    else if(neg_diff_vsync)
        coord_y2_r <= 16'd0;
    else if(valid_y > coord_y2_r)
        coord_y2_r <= valid_y;
    else
        coord_y2_r <= coord_y2_r;
end

// outputs--------------------------------------------------------------------------

// coord_vsync & coord_href
assign coord_vsync = diff_vsync;
assign coord_href  = diff_href ;

// x1 & x2 & y1 & y2
always @(posedge clk or negedge rst_n) begin
    if(~rst_n)begin
        coord_x1 <= 16'd0;
        coord_x2 <= 16'd0;
        coord_y1 <= 16'd0;
        coord_y2 <= 16'd0;
    end
    else if(pos_diff_vsync)begin
        coord_x1 <= coord_x1_r;
        coord_x2 <= coord_x2_r;
        coord_y1 <= coord_y1_r;
        coord_y2 <= coord_y2_r;
    end
    else begin
        coord_x1 <= coord_x1;
        coord_x2 <= coord_x2;
        coord_y1 <= coord_y1;
        coord_y2 <= coord_y2;
    end
end
endmodule